<!DOCTYPE html>
<html class="client-nojs vector-feature-language-in-header-enabled vector-feature-language-in-main-page-header-disabled vector-feature-page-tools-pinned-disabled vector-feature-toc-pinned-clientpref-0 vector-toc-not-available vector-feature-main-menu-pinned-disabled vector-feature-limited-width-clientpref-1 vector-feature-limited-width-content-enabled vector-feature-custom-font-size-clientpref-1 vector-feature-appearance-pinned-clientpref-0 skin-theme-clientpref-day vector-sticky-header-enabled" lang="de" dir="ltr"><head>
<meta charset="UTF-8">
<title>PL/pgSQL</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/png" href="../_res_/favicon.png">
<link rel="canonical" href="https://de.wikipedia.org/wiki/PL%2FpgSQL"> <link href="../_mw_/ext.cite.styles.css" rel="stylesheet" type="text/css">
<link href="../_mw_/ext.pygments.css" rel="stylesheet" type="text/css">
<link href="../_mw_/ext.wikimediamessages.styles.css" rel="stylesheet" type="text/css">
<link href="../_mw_/skins.vector.icons.css" rel="stylesheet" type="text/css">
<link href="../_mw_/skins.vector.search.codex.styles.css" rel="stylesheet" type="text/css">
<link href="../_mw_/skins.vector.styles.css" rel="stylesheet" type="text/css">
<meta name="ResourceLoaderDynamicStyles" content="">
<link href="../_mw_/ext.gadget.citeRef.css" rel="stylesheet" type="text/css">
<link href="../_mw_/ext.gadget.defaultPlainlinks.css" rel="stylesheet" type="text/css">
<link href="../_mw_/ext.gadget.dewikiCommonHide.css" rel="stylesheet" type="text/css">
<link href="../_mw_/ext.gadget.dewikiCommonLayout.css" rel="stylesheet" type="text/css">
<link href="../_mw_/ext.gadget.dewikiCommonStyle.css" rel="stylesheet" type="text/css">
<link href="../_mw_/ext.gadget.dewikiDarkmode.css" rel="stylesheet" type="text/css">
<link href="../_mw_/ext.gadget.dewikiResponsive.css" rel="stylesheet" type="text/css">
<link href="../_mw_/ext.gadget.specialSearch.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="../_mw_/site.styles.css">
<link rel="stylesheet" type="text/css" href="../_mw_/noscript.css">
<link rel="stylesheet" type="text/css" href="../_res_/footer.css">
<link rel="stylesheet" type="text/css" href="../_res_/vector-2022.css">
</head>
<body class="skin--responsive skin-vector skin-vector-search-vue mediawiki ltr sitedir-ltr mw-hide-empty-elt ns-0 ns-subject page-PL_pgSQL rootpage-PL_pgSQL skin-vector-2022 action-view">
<div class="mw-page-container">
<div class="mw-page-container-inner">
<div class="mw-content-container">
<main id="content" class="mw-body">
<header class="mw-body-header vector-page-titlebar">
<h1 id="firstHeading" class="firstHeading mw-first-heading"><span class="mw-page-title-main">PL/pgSQL</span></h1>
</header>
<a id="top"></a>
<div id="bodyContent" class="vector-body ve-init-mw-desktopArticleTarget-targetContainer" aria-labelledby="firstHeading" data-mw-ve-target-container="">
<div id="contentSub">
<div id="mw-content-subtitle"></div>
</div>
<div id="mw-content-text" class="mw-body-content mw-content-ltr" lang="de" dir="ltr"><div class="mw-content-ltr mw-parser-output" lang="de" dir="ltr"><table class="float-right infobox toccolours toptextcells" style="font-size:90%; margin-top:0; width:21em;">
<tbody><tr>
<th colspan="2" class="hintergrundfarbe6" style="font-size:larger;">PL/pgSQL
</th></tr>
<tr>
<td colspan="2" class="notheme" style="text-align:center; background-color:#f8f9fa;">
</td></tr>
<tr>
<th colspan="2" class="hintergrundfarbe5" style="font-size:105%; text-align:center;">Basisdaten
</th></tr>
<tr>
<td><b><a href="../Programmierparadigma" title="Programmierparadigma">Paradigmen</a>:</b>
</td>
<td>prozedural
</td></tr>
<tr>
<td><b>Erscheinungsjahr:</b>
</td>
<td><span class="wikidata-content">30. Oktober 1998</span>
</td></tr>
<tr>
<td><b>Entwickler:</b>
</td>
<td><a rel="nofollow" class="external text" href="https://www.postgresql.org/community/contributors/">PostgreSQL-Team</a>
</td></tr>
<tr>
<td><b>Aktuelle <a href="../Version_(Software)" title="Version (Software)">Version</a>:</b>
</td>
<td style="white-space:nowrap;">12 <small>(3. Oktober 2019)</small>
</td></tr>
<tr>
<td><b><a href="../Typisierung_(Informatik)" title="Typisierung (Informatik)">Typisierung</a>:</b>
</td>
<td><a href="../Starke_Typisierung" title="Starke Typisierung">stark</a>, <a href="../Statische_Typisierung" title="Statische Typisierung">statisch</a>, <a href="../Explizite_Typisierung" class="mw-redirect" title="Explizite Typisierung">explizit</a>
</td></tr>
<tr>
<td><b>Beeinflusst von:</b>
</td>
<td><span class="wikidata-content"><a href="../PL/SQL" title="PL/SQL">PL/SQL</a>, <a href="../Ada_(Programmiersprache)" title="Ada (Programmiersprache)">Ada</a></span>
</td></tr>
<tr>
<td><b><a href="../Betriebssystem" title="Betriebssystem">Betriebssystem</a>:</b>
</td>
<td><a href="../Unix-Derivat" class="mw-redirect" title="Unix-Derivat">Unix-Derivate</a>, <a href="../Linux" title="Linux">Linux</a>, <a href="../Microsoft_Windows" title="Microsoft Windows">Windows</a>
</td></tr>
<tr>
<td><b><a href="../Lizenz" title="Lizenz">Lizenz</a>:</b>
</td>
<td>PostgreSQL Lizenz<sup id="cite_ref-1" class="reference"><a href="#cite_note-1"><span class="cite-bracket">[</span>1<span class="cite-bracket">]</span></a></sup>
</td></tr>
<tr>
<td colspan="2" class="hintergrundfarbe5" style="text-align:center;"><a rel="nofollow" class="external text" href="https://www.postgresql.org/">postgresql.org</a>
</td></tr></tbody></table>
<p><b>PL/pgSQL</b> (<b>Procedural Language/PostgreSQL Structured Query Language</b>) ist eine prozedurale Sprache der <a href="../Objektrelationale_Datenbank" title="Objektrelationale Datenbank">objektrelationalen Datenbank</a> <a href="../PostgreSQL" title="PostgreSQL">PostgreSQL</a>. Die Syntax von PL/pgSQL ist wie bei <a href="../PL/SQL" title="PL/SQL">PL/SQL</a> auf <a href="../Oracle" title="Oracle">Oracle</a>-Datenbanksystemen stark an <a href="../Ada_(Programmiersprache)" title="Ada (Programmiersprache)">Ada</a> angelehnt.
</p><p>PL/pgSQL wurde zur Erweiterung des SQL-Funktionsumfangs eingeführt, dabei kann PL/pgSQL-Code als <a href="../Stored_Procedure" class="mw-redirect" title="Stored Procedure">Stored Procedure</a> in der Datenbank selbst gespeichert sein. Unterstützt werden <a href="../Variable_(Programmierung)" title="Variable (Programmierung)">Variablen</a>, <a href="../Verzweigung_(Programmierung)" class="mw-redirect" title="Verzweigung (Programmierung)">Bedingungen</a>, <a href="../Schleife_(Programmierung)" title="Schleife (Programmierung)">Schleifen</a>, <a href="../Funktion_(Programmierung)" title="Funktion (Programmierung)">Funktionen</a>, Datenbankcursor und <a href="../Ausnahmebehandlung" title="Ausnahmebehandlung">Ausnahmebehandlungen</a>. PL/pgSQL-Code kann sowohl aus SQL-Kommandos als auch aus <a href="../Datenbanktrigger" title="Datenbanktrigger">Datenbanktriggern</a> heraus aufgerufen werden.
</p><p>Mit Hilfe der prozeduralen Erweiterung lassen sich SQL-Befehle direkt im PostgreSQL-Server dynamisch erzeugen und müssen nicht mehr als Text über eine Datenbankschnittstelle übergeben werden, wie dies z. B. bei <a href="../Open_Database_Connectivity" title="Open Database Connectivity">ODBC</a>, <a href="../Java_Database_Connectivity" title="Java Database Connectivity">JDBC</a> und <a href="../OLE_DB" title="OLE DB">OLE DB</a> der Fall ist, sondern können direkt in der Datenbank erstellt und ausgeführt werden.
</p>
<div class="mw-heading mw-heading2"><h2 id="Verwendung">Verwendung</h2></div>
<ul><li>PL/pgSQL-Code kann von einem <a href="../Frontend_und_Backend" title="Frontend und Backend">Datenbank-Frontend</a> an PostgreSQL übergeben und dort direkt abgearbeitet werden.</li>
<li>PL/pgSQL-Code kann (als <a href="../Stored_Procedure" class="mw-redirect" title="Stored Procedure">Stored Procedure</a>) dauerhaft in der Datenbank gespeichert werden um den Funktionsumfang der Datenbank zu erweitern.</li>
<li>Über Berechtigungen (sogenannte „Rollen“) kann jeder Benutzer oder jede Benutzergruppe der Datenbank die Funktionen nutzen, die für deren Rolle vorgesehen sind. Auf diese Weise lässt sich die Sicherheit vor unbefugten Zugriffen deutlich verbessern.</li>
<li>Verwendung in <a href="../Datenbanktrigger" title="Datenbanktrigger">Datenbanktriggern</a></li>
<li>Die Performance lässt sich oft enorm steigern, wenn PL/pgSQL-Programme direkt in der Datenbank ausgeführt werden, insbesondere wenn sich dadurch die Kommunikation zwischen Prozessen oder der Netzwerkverkehr, falls Datenbank und Anwendungsserver auf unterschiedlicher Hardware ausgeführt werden, vermeiden lässt.</li></ul>
<div class="mw-heading mw-heading2"><h2 id="Grundlegender_Aufbau">Grundlegender Aufbau</h2></div>
<p>PL/pgSQL-Programme bestehen aus Blöcken:
<sup id="cite_ref-2" class="reference"><a href="#cite_note-2"><span class="cite-bracket">[</span>2<span class="cite-bracket">]</span></a></sup>
</p>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="k">DECLARE</span>
<span class="w"> </span><span class="c1">-- Deklarationsblock</span>
<span class="w"> </span><span class="c1">-- Der DECLARE Abschnitt ist optional</span>
<span class="k">BEGIN</span>
<span class="w"> </span><span class="c1">-- Ausführungsteil</span>
<span class="n">EXCEPTION</span>
<span class="w"> </span><span class="c1">-- Ausnahmeverarbeitung</span>
<span class="w"> </span><span class="c1">-- Der EXCEPTION Abschnitt ist optional</span>
<span class="k">END</span><span class="p">;</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Beispiel">Beispiel</h2></div>
<p>Das Beispiel schreibt eine "Hallo Welt"-Notiz.
</p>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="c1">-- Eine Funktion namens hallo wird angelegt.</span>
<span class="c1">-- "void" bedeutet, dass nichts zurückgegeben wird.</span>
<span class="k">CREATE</span><span class="w"> </span><span class="k">OR</span><span class="w"> </span><span class="k">REPLACE</span><span class="w"> </span><span class="k">FUNCTION</span><span class="w"> </span><span class="n">hallo</span><span class="p">()</span><span class="w"> </span><span class="k">RETURNS</span><span class="w"> </span><span class="nb">void</span><span class="w"> </span><span class="k">AS</span>
<span class="w"> </span><span class="c1">-- Der Funktionskörper wird in $$-Stringliteralen gekapselt.</span>
<span class="w"> </span><span class="c1">-- hier steht $body$ zwischen den $ Zeichen.</span>
<span class="w"> </span><span class="c1">-- Der Text zwischen den $ Zeichen muss eine Länge von mindestens 0 Zeichen aufweisen.</span>
<span class="w"> </span><span class="s">$</span><span class="dl">body</span><span class="s">$</span>
<span class="s"> BEGIN</span>
<span class="s"> RAISE NOTICE 'Hallo Welt'; -- eine Notiz wird aufgerufen</span>
<span class="s"> END;</span>
<span class="s"> $</span><span class="dl">body</span><span class="s">$</span><span class="w"> </span><span class="c1">-- Ende des Funktionskörpers</span>
<span class="k">LANGUAGE</span><span class="w"> </span><span class="n">plpgsql</span><span class="p">;</span><span class="w"> </span><span class="c1">-- die Sprache des Funktionskörpers muss angegeben werden</span>
<span class="k">SELECT</span><span class="w"> </span><span class="n">hallo</span><span class="p">();</span>
<span class="w"> </span><span class="c1">-- Die Funktion wird mit einem SELECT aufgerufen.</span>
<span class="w"> </span><span class="c1">-- Die Ausgabe der Notiz erfolgt in der Konsole</span>
<span class="k">DROP</span><span class="w"> </span><span class="k">FUNCTION</span><span class="w"> </span><span class="n">hallo</span><span class="p">();</span>
<span class="c1">-- Löschen ("droppen") der Funktion, die wir gerade angelegt haben.</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Variablendefinitionen">Variablendefinitionen</h2></div>
<p>Variablen werden im optionalen Abschnitt <code>DECLARE</code> definiert und optional initialisiert.
</p>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="k">CREATE</span><span class="w"> </span><span class="k">FUNCTION</span><span class="w"> </span><span class="n">foo</span><span class="p">()</span><span class="w"> </span><span class="k">RETURNS</span><span class="w"> </span><span class="nb">void</span><span class="w"> </span><span class="k">AS</span>
<span class="s">$</span><span class="dl">BODY</span><span class="s">$</span>
<span class="w"> </span><span class="k">DECLARE</span>
<span class="w"> </span><span class="n">zahl_antwort</span><span class="w"> </span><span class="nb">INTEGER</span><span class="p">;</span>
<span class="w"> </span><span class="n">zahl_lösung</span><span class="w"> </span><span class="nb">INTEGER</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mf">42</span><span class="p">;</span>
<span class="w"> </span><span class="k">BEGIN</span>
<span class="w"> </span><span class="n">zahl_antwort</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="n">zahl_lösung</span><span class="p">;</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'Die Antwort lautet %.'</span><span class="p">,</span><span class="w"> </span><span class="n">zahl_antwort</span><span class="p">;</span><span class="c1">-- % wird durch die Variable ersetzt</span>
<span class="w"> </span><span class="c1">-- return true;</span>
<span class="w"> </span><span class="k">END</span><span class="p">;</span>
<span class="s">$</span><span class="dl">BODY</span><span class="s">$</span><span class="w"> </span><span class="k">LANGUAGE</span><span class="w"> </span><span class="n">plpgsql</span><span class="p">;</span>
</pre></div>
<p><code>:=</code> ist der Zuweisungsoperator, mit dem man einer Variable einen Wert zuweist. Im DECLARE Abschnitt kann für Zuweisungen alternativ auch <code>DEFAULT</code> verwendet werden.
</p>
<div class="mw-heading mw-heading3"><h3 id="Zahlenvariablen">Zahlenvariablen</h3></div>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="n">variablenname</span><span class="w"> </span><span class="nb">NUMERIC</span><span class="p">(</span><span class="k">precision</span><span class="p">,</span><span class="w"> </span><span class="n">scale</span><span class="p">)</span><span class="w"> </span><span class="k">DEFAULT</span><span class="w"> </span><span class="n">wert</span><span class="p">;</span>
</pre></div>
<p>Um eine Zahlenvariable zu definieren, schreibt man den Variablennamen gefolgt vom Variablentyp <code>NUMERIC</code>.
</p><p>Hinter diesem schreibt man in runden Klammern die Genauigkeit precision sowie optional ein Komma und die Anzahl an Nachkommastellen scale. Gibt man <code>NUMERIC</code> ohne Klammern an gelten für die Genauigkeit bis zu 131072 Stellen vor dem Dezimalpunkt und bis zu 16383 Stellen nach dem Dezimalpunkt.
</p><p>Genauigkeit entspricht in diesem Fall der Anzahl an Stellen, welche die Variable enthalten kann, und <i>nicht</i> dem Wertebereich.
</p><p>Auswahl weiterer Datentypen für Zahlenvariablen:
</p>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="nb">SMALLINT</span><span class="p">,</span><span class="w"> </span><span class="nb">INTEGER</span><span class="p">,</span><span class="w"> </span><span class="nb">BIGINT</span><span class="p">,</span><span class="w"> </span><span class="nb">DECIMAL</span><span class="p">,</span><span class="w"> </span><span class="nb">REAL</span><span class="p">,</span><span class="w"> </span><span class="nb">DOUBLE PRECISION</span>
</pre></div>
<div class="mw-heading mw-heading3"><h3 id="Textvariablen">Textvariablen</h3></div>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="n">variablenname1</span><span class="w"> </span><span class="nb">VARCHAR</span><span class="p">(</span><span class="n">length</span><span class="p">)</span><span class="w"> </span><span class="p">:</span><span class="o">=</span><span class="w"> </span><span class="s1">'Text'</span><span class="p">;</span>
<span class="nb">VARCHAR</span><span class="p">(</span><span class="n">length</span><span class="p">)</span><span class="w"> </span><span class="k">COLLATE</span><span class="w"> </span><span class="n">collation_name</span><span class="p">;</span>
</pre></div>
<p>Um eine Textvariable zu definieren, schreibt man den Variablennamen gefolgt vom Variablentyp <code>VARCHAR</code>.
Hinter diesem schreibt man die Anzahl der Zeichen, die in der Variable gespeichert werden können, in Klammern.
Soll die Textvariable nach sprach- oder benutzerdefinierten Kriterien sortiert werden, kann man das Schlüsselwort <code>COLLATE</code> gefolgt vom Collationsname z. B. "en_US" verwenden.
Weiterer Datentypen für Textvariablen sind:
</p>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="nb">CHAR</span><span class="p">,</span><span class="w"> </span><span class="nb">TEXT</span>
</pre></div>
<div class="mw-heading mw-heading3"><h3 id="Boolean">Boolean</h3></div>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="n">variablenname</span><span class="w"> </span><span class="nb">BOOLEAN</span><span class="w"> </span><span class="p">:</span><span class="o">=</span><span class="w"> </span><span class="k">TRUE</span><span class="p">;</span>
</pre></div>
<p>Kann <code>TRUE</code>, <code>FALSE</code> oder <code><a href="../Nullwert" title="Nullwert">NULL</a></code> sein.
</p>
<div class="mw-heading mw-heading3"><h3 id="Datum_und_Uhrzeit">Datum und Uhrzeit</h3></div>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="n">variablenname</span><span class="w"> </span><span class="nb">DATE</span><span class="w"> </span><span class="p">:</span><span class="o">=</span><span class="w"> </span><span class="n">TO_DATE</span><span class="p">(</span><span class="w"> </span><span class="s1">'01.01.2005'</span><span class="w"> </span><span class="p">,</span><span class="w"> </span><span class="s1">'DD.MM.YYYY'</span><span class="p">);</span>
</pre></div>
<p>Um eine Datumsvariable zu definieren schreibt man den Variablennamen gefolgt vom Variablentyp <code>DATE</code>.
Zum Konvertieren von Datum und Uhrzeit stellt PostgreSQL eine Reihe von Funktionen zur Verfügung. Hier wurde <code>TO_DATE()</code> verwendet. Diese Funktion wandelt den Text zwischen den ersten Hochkommas in ein Datum mit dem angegebenen Format zwischen den zweiten Hochkommas um. Weitere Datum- und Zeit-Datentypen sind:
</p>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="nb">TIMESTAMP</span><span class="w"> </span><span class="p">[(</span><span class="n">p</span><span class="p">)]</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="nb">WITHOUT TIME ZONE</span><span class="w"> </span><span class="p">]</span>
<span class="nb">TIMESTAMP</span><span class="w"> </span><span class="p">[(</span><span class="n">p</span><span class="p">)]</span><span class="w"> </span><span class="nb">WITH TIME ZONE</span>
<span class="nb">DATE</span>
<span class="nb">TIME</span><span class="w"> </span><span class="p">[(</span><span class="n">p</span><span class="p">)]</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="nb">WITHOUT TIME ZONE</span><span class="w"> </span><span class="p">]</span>
<span class="nb">TIME</span><span class="w"> </span><span class="p">[(</span><span class="n">p</span><span class="p">)]</span><span class="w"> </span><span class="nb">WITH TIME ZONE</span>
<span class="nb">INTERVAL</span><span class="w"> </span><span class="p">[</span><span class="w"> </span><span class="n">FIELDS</span><span class="w"> </span><span class="p">]</span><span class="w"> </span><span class="p">[(</span><span class="n">p</span><span class="p">)]</span>
</pre></div>
<p>Mit dem optionalen Statement <code>(p)</code> kann die Anzahl der Stellen der Sekundenbruchteile präzisiert werden.
</p>
<div class="mw-heading mw-heading3"><h3 id="Datentyp_über_Tabelle_oder_Spalte_festlegen"><span id="Datentyp_.C3.BCber_Tabelle_oder_Spalte_festlegen"></span>Datentyp über Tabelle oder Spalte festlegen</h3></div>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="n">Variablenname</span><span class="w"> </span><span class="n">tabellenname</span><span class="o">%</span><span class="n">ROWTYPE</span><span class="p">;</span>
<span class="n">Variablenname</span><span class="w"> </span><span class="n">tabellenname</span><span class="mf">.</span><span class="n">spaltenname</span><span class="o">%</span><span class="k">TYPE</span><span class="p">;</span>
</pre></div>
<p><code>%TYPE</code> definiert eine Variable des Typs der angegebenen Spalte.
<code>%ROWTYPE</code> definiert eine Variable des Typs der angegebenen Tabelle. Weil jede Tabelle in PostgreSQL implizit einen gleichnamigen Zeilentyp generiert, darf <code>%ROWTYPE</code> auch weggelassen werden.
</p><p>Beispiel:
</p>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="k">CREATE</span><span class="w"> </span><span class="k">FUNCTION</span><span class="w"> </span><span class="n">foo</span><span class="p">()</span><span class="w"> </span><span class="k">RETURNS</span><span class="w"> </span><span class="nb">void</span><span class="w"> </span><span class="k">AS</span>
<span class="s">$</span><span class="dl">BODY</span><span class="s">$</span>
<span class="w"> </span><span class="k">DECLARE</span>
<span class="w"> </span><span class="n">t_row</span><span class="w"> </span><span class="n">tab</span><span class="nb">%ROWTYPE</span><span class="p">;</span>
<span class="w"> </span><span class="k">BEGIN</span>
<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">t_row</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">tab</span><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">Z</span><span class="o">=</span><span class="mf">1</span><span class="p">;</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'Y*4+Z*2= %.'</span><span class="p">,</span><span class="w"> </span><span class="n">t_row</span><span class="mf">.</span><span class="n">y</span><span class="w"> </span><span class="o">*</span><span class="mf">4</span><span class="o">+</span><span class="w"> </span><span class="n">t_row</span><span class="mf">.</span><span class="n">z</span><span class="o">*</span><span class="mf">2</span><span class="p">;</span>
<span class="w"> </span><span class="cm">/*return true;*/</span>
<span class="w"> </span><span class="k">END</span><span class="p">;</span>
<span class="s">$</span><span class="dl">BODY</span><span class="s">$</span><span class="w"> </span><span class="k">LANGUAGE</span><span class="w"> </span><span class="n">plpgsql</span><span class="p">;</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Steuerung_des_Programmablaufs">Steuerung des Programmablaufs</h2></div>
<div class="mw-heading mw-heading3"><h3 id="Rückgabe_der_Funktion"><span id="R.C3.BCckgabe_der_Funktion"></span>Rückgabe der Funktion</h3></div>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="k">RETURN</span><span class="w"> </span><span class="k">expression</span><span class="p">;</span>
<span class="k">RETURN</span><span class="w"> </span><span class="k">NEXT</span><span class="w"> </span><span class="k">expression</span><span class="p">;</span>
<span class="k">RETURN</span><span class="w"> </span><span class="n">QUERY</span><span class="w"> </span><span class="n">query</span><span class="p">;</span>
<span class="k">RETURN</span><span class="w"> </span><span class="n">QUERY</span><span class="w"> </span><span class="k">EXECUTE</span><span class="w"> </span><span class="n">command</span><span class="o">-</span><span class="n">string</span><span class="p">;</span>
<span class="k">RETURN</span><span class="w"> </span><span class="n">QUERY</span><span class="w"> </span><span class="k">EXECUTE</span><span class="w"> </span><span class="n">command</span><span class="o">-</span><span class="n">string</span><span class="w"> </span><span class="k">USING</span><span class="w"> </span><span class="k">expression</span><span class="p">;</span>
</pre></div>
<p>Mit dem Schlüsselwort <code>RETURN</code> wird die Rückgabe an die Funktion definiert. Soll die Funktion Datensätze mit Hilfe des Schlüsselwortes <code>SETOF</code> zurückgeben, kann das mit <code>RETURN NEXT</code> oder <code>RETURN QUERY</code> realisiert werden. Mit Hilfe von <code>USING</code> können Parameter in den SQL-Befehl eingefügt werden.
</p><p>In folgendem Beispiel wird <code>RETURN NEXT</code> verwendet:
</p>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="k">BEGIN</span><span class="p">;</span><span class="w"> </span><span class="c1">-- eine Transaktion starten</span>
<span class="w"> </span><span class="k">CREATE</span><span class="w"> </span><span class="k">TABLE</span><span class="w"> </span><span class="n">foo</span><span class="w"> </span><span class="p">(</span><span class="n">fooid</span><span class="w"> </span><span class="nb">INT</span><span class="p">,</span><span class="w"> </span><span class="n">foosubid</span><span class="w"> </span><span class="nb">INT</span><span class="p">,</span><span class="w"> </span><span class="n">fooname</span><span class="w"> </span><span class="nb">TEXT</span><span class="p">);</span><span class="w"> </span><span class="c1">-- Tabelle foo neu erstellen</span>
<span class="w"> </span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">foo</span><span class="w"> </span><span class="k">VALUES</span><span class="w"> </span><span class="p">(</span><span class="mf">1</span><span class="p">,</span><span class="w"> </span><span class="mf">2</span><span class="p">,</span><span class="w"> </span><span class="s1">'drei'</span><span class="p">);</span>
<span class="w"> </span><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="n">foo</span><span class="w"> </span><span class="k">VALUES</span><span class="w"> </span><span class="p">(</span><span class="mf">4</span><span class="p">,</span><span class="w"> </span><span class="mf">5</span><span class="p">,</span><span class="w"> </span><span class="s1">'neun'</span><span class="p">);</span>
<span class="w"> </span><span class="c1">-- Funktion getAllFoo anlegen. Die Funktion soll alle Datensätze aus foo liefern,</span>
<span class="w"> </span><span class="c1">-- deren fooid größer als 0 ist:</span>
<span class="w"> </span><span class="k">CREATE</span><span class="w"> </span><span class="k">OR</span><span class="w"> </span><span class="k">REPLACE</span><span class="w"> </span><span class="k">FUNCTION</span><span class="w"> </span><span class="n">getAllFoo</span><span class="p">()</span><span class="w"> </span><span class="k">RETURNS</span><span class="w"> </span><span class="k">SETOF</span><span class="w"> </span><span class="n">foo</span><span class="w"> </span><span class="k">AS</span>
<span class="w"> </span><span class="s">$</span><span class="dl">BODY</span><span class="s">$ -- Beginn der PL/pgSQL Prozedur</span>
<span class="s"> DECLARE</span>
<span class="s"> r foo%rowtype;</span>
<span class="s"> BEGIN</span>
<span class="s"> FOR r IN</span>
<span class="s"> SELECT * FROM foo WHERE fooid > 0</span>
<span class="s"> LOOP</span>
<span class="s"> -- hier könnten weitere Anweisungen stehen</span>
<span class="s"> RETURN NEXT r; -- Rückgabe des aktuellen Datensatzes aus SELECT</span>
<span class="s"> END LOOP;</span>
<span class="s"> RETURN;</span>
<span class="s"> END</span>
<span class="s"> $</span><span class="dl">BODY</span><span class="s">$</span><span class="w"> </span><span class="c1">-- Ende der PL/pgSQL Prozedur</span>
<span class="w"> </span><span class="k">LANGUAGE</span><span class="w"> </span><span class="n">plpgsql</span><span class="p">;</span>
<span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">getallfoo</span><span class="p">();</span><span class="w"> </span><span class="c1">-- Dieses Select zeigt alle Datensätze die die Funktion liefert.</span>
<span class="k">ROLLBACK</span><span class="p">;</span><span class="w"> </span><span class="c1">-- Das war ein Test, es soll nichts gespeichert werden</span>
</pre></div>
<div class="mw-heading mw-heading3"><h3 id="Verzweigung_des_Programmablaufs">Verzweigung des Programmablaufs</h3></div>
<p>Mit Hilfe von Bedingungen kann der Programmablauf gesteuert werden. Je nach Situation werden die Befehle im dafür vorgesehenen Abschnitt abgearbeitet.
</p>
<div class="mw-heading mw-heading4"><h4 id="IF_THEN">IF THEN</h4></div>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="k">IF</span><span class="w"> </span><span class="n">boolean_expression</span><span class="w"> </span><span class="k">THEN</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="p">;</span>
<span class="k">IF</span><span class="w"> </span><span class="n">boolean_expression</span><span class="w"> </span><span class="k">THEN</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="k">ELSE</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="p">;</span>
<span class="k">IF</span><span class="w"> </span><span class="n">boolean_expression</span><span class="w"> </span><span class="k">THEN</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="n">ELSIF</span><span class="w"> </span><span class="n">boolean_expression</span><span class="w"> </span><span class="k">THEN</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="p">;</span>
<span class="k">IF</span><span class="w"> </span><span class="n">boolean_expression</span><span class="w"> </span><span class="k">THEN</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="n">ELSIF</span><span class="w"> </span><span class="n">boolean_expression</span><span class="w"> </span><span class="k">THEN</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="k">ELSE</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="p">;</span>
</pre></div>
<p><code>IF</code> prüft, ob eine Bedingung erfüllt ist. Trifft die Bedingung zu, wird der Code nach dem <code>THEN</code> und ausgeführt und ansonsten übersprungen. Mit <code>ELSIF</code> können weitere Bedingungen hinzugefügt werden. Ist eine <code>ELSE</code> vorhanden wird der darauf folgende Code ausgeführt, falls keine der Bedingungen zutrifft. Trifft mehr als eine der Bedingungen zu, wird nur die erste wahre Bedingung ausgeführt, und alle anderen wahren Bedingungen übersprungen. Die Schlüsselwörter <code>ELSEIF</code> und <code>ELSIF</code> sind <a href="../Synonym" title="Synonym">Synonyme</a>.
</p>
<div class="mw-heading mw-heading4"><h4 id="CASE_WHEN">CASE WHEN</h4></div>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="k">CASE</span><span class="w"> </span><span class="n">search_expression</span><span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="n">expressions</span><span class="w"> </span><span class="k">THEN</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">CASE</span><span class="p">;</span>
<span class="k">CASE</span><span class="w"> </span><span class="n">search_expression</span><span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="n">expressions</span><span class="w"> </span><span class="k">THEN</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="k">ELSE</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">CASE</span><span class="p">;</span>
<span class="k">CASE</span><span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="n">boolean_expression</span><span class="w"> </span><span class="k">THEN</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">CASE</span><span class="p">;</span>
<span class="k">CASE</span><span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="n">boolean_expression</span><span class="w"> </span><span class="k">THEN</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="k">ELSE</span><span class="w"> </span><span class="n">statements</span><span class="p">;</span><span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">CASE</span><span class="p">;</span>
<span class="c1">-- Optional darf "WHEN … THEN …" beliebig oft vorkommen;</span>
</pre></div>
<p>Die <code>CASE</code>-Anweisung bietet zwei unterschiedliche Wege, im ersten Fall wird nach dem <code>CASE</code> ein Suchausdruck angegeben. Dieser Ausdruck wird im Ausdruck der <code>WHEN</code> folgt gesucht und anschließend wird der Code nach dem <code>THEN</code> ausgeführt. Nach dem <code>WHEN</code> können auch mehrere durch Kommas getrennte Ausdrücke ausgewertet werden.
Im zweiten Fall folgt dem <code>CASE</code> das <code>WHEN</code> direkt, und danach wird eine Bedingung angegeben. Trifft diese zu wird der Code nach dem <code>THEN</code> ausgeführt.
In beiden Fällen wird der dem <code>ELSE</code> folgende Code ausgeführt, wenn nichts gefunden wurde. mit <code>END CASE</code> wird die <code>CASE</code>-Anweisung abgeschlossen. Wie zuvor bei <code>IF THEN</code> wird nur der der ersten gültigen Bedingung folgende Codeabschnitt ausgeführt.
</p><p>Beispiel für Verzweigung des Programmablaufes mit <code>IF THEN</code> und <code>CASE WHEN</code>:
</p>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="k">CREATE</span><span class="w"> </span><span class="k">FUNCTION</span><span class="w"> </span><span class="n">foo</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span><span class="w"> </span><span class="k">RETURNS</span><span class="w"> </span><span class="nb">void</span><span class="w"> </span><span class="k">AS</span>
<span class="s">$</span><span class="dl">BODY</span><span class="s">$</span>
<span class="w"> </span><span class="k">DECLARE</span>
<span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="nb">INTEGER</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nv">$1</span><span class="p">;</span>
<span class="w"> </span><span class="k">BEGIN</span>
<span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mf">50</span><span class="w"> </span><span class="k">then</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'true %'</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">;</span>
<span class="w"> </span><span class="k">ELSIF</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mf">25</span><span class="w"> </span><span class="k">then</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'1. elsif %'</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">;</span>
<span class="w"> </span><span class="k">ELSIF</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mf">20</span><span class="w"> </span><span class="k">then</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'2. elsif %'</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">;</span>
<span class="w"> </span><span class="k">ELSE</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'if false else %'</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">;</span>
<span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">IF</span><span class="p">;</span>
<span class="w"> </span><span class="k">CASE</span><span class="w"> </span><span class="n">I</span>
<span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="mf">21</span><span class="p">,</span><span class="mf">23</span><span class="p">,</span><span class="mf">25</span><span class="p">,</span><span class="mf">27</span><span class="w"> </span><span class="k">THEN</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'1. einfache when %'</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">;</span>
<span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="mf">22</span><span class="p">,</span><span class="mf">24</span><span class="p">,</span><span class="mf">26</span><span class="p">,</span><span class="mf">28</span><span class="w"> </span><span class="k">THEN</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'2. einfache when %'</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">;</span>
<span class="w"> </span><span class="k">ELSE</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'einfache case else %'</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">;</span>
<span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">CASE</span><span class="p">;</span>
<span class="w"> </span><span class="k">CASE</span>
<span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="k">BETWEEN</span><span class="w"> </span><span class="mf">20</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="mf">25</span><span class="w"> </span><span class="k">THEN</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'1. gesuchte when %'</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">;</span>
<span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="n">I</span><span class="w"> </span><span class="k">BETWEEN</span><span class="w"> </span><span class="mf">26</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="mf">30</span><span class="w"> </span><span class="k">THEN</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'2. gesuchte when %'</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">;</span>
<span class="w"> </span><span class="k">ELSE</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'gesuchte case else %'</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="p">;</span>
<span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">CASE</span><span class="p">;</span>
<span class="w"> </span><span class="k">END</span><span class="p">;</span>
<span class="s">$</span><span class="dl">BODY</span><span class="s">$</span><span class="w"> </span><span class="k">LANGUAGE</span><span class="w"> </span><span class="n">plpgsql</span><span class="p">;</span>
<span class="k">Select</span><span class="w"> </span><span class="n">foo</span><span class="p">(</span><span class="mf">27</span><span class="p">);</span>
</pre></div>
<div class="mw-highlight mw-highlight-lang-text mw-content-ltr" dir="ltr"><pre><span></span>Ausgabe mit pgAdmin:
HINWEIS: 1. elsif 27
HINWEIS: 1. einfache when 27
HINWEIS: 2. gesuchte when 27
Total query runtime: 35 ms.
1 row retrieved.
</pre></div>
<div class="mw-heading mw-heading3"><h3 id="Schleifen">Schleifen</h3></div>
<p>Mit den Schlüsselwörtern <code>LOOP, EXIT, CONTINUE, WHILE, FOR</code> und <code>FOREACH</code> können Anweisungsblöcke wiederholt durchlaufen werden.
</p>
<div class="mw-heading mw-heading4"><h4 id="Einfache_LOOP_Schleife">Einfache LOOP Schleife</h4></div>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="n">LOOP</span>
<span class="w"> </span><span class="n">statements</span><span class="p">;</span>
<span class="w"> </span><span class="n">EXIT</span><span class="p">;</span>
<span class="k">END</span><span class="w"> </span><span class="n">LOOP</span><span class="p">;</span>
<span class="w"> </span><span class="o"><<</span><span class="k">label</span><span class="o">>></span>
<span class="n">LOOP</span>
<span class="w"> </span><span class="n">statements</span><span class="p">;</span>
<span class="w"> </span><span class="n">EXIT</span><span class="w"> </span><span class="k">label</span><span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="n">boolean_expression</span><span class="w"> </span><span class="p">;</span>
<span class="k">END</span><span class="w"> </span><span class="n">LOOP</span><span class="w"> </span><span class="k">label</span><span class="w"> </span><span class="p">;</span>
</pre></div>
<p>Die einfache <code>LOOP</code> Schleife endet sobald ein <code>EXIT</code> die Schleife oder ein <code>RETURN</code> die Funktion beendet. Folgt hinter dem <code>EXIT</code> ein <code>WHEN</code> mit einer Bedingung, wird die Schleife nur bei erfüllter Bedingung verlassen. PL/pgSQL erlaubt es Schleifen zu benennen. Der <code>LOOP</code> Block wird auf jeden Fall bis zum <code>EXIT</code> durchlaufen, egal ob die Bedingung auch schon zuvor zutraf. Mit der <code>CONTINUE WHEN</code> Anweisung kann ein Teil der Schleife bedingt ausgeführt werden.
</p><p>Der Name eines Blocks wird zwischen doppelten größerkleiner Zeichen <<>>festgelegt wie <<label>> oberhalb. Die Benennung verbessert die Lesbarkeit des Codes.
</p><p>In diesem Beispiel wird der benannte Block "ablock" solange durchlaufen bis j=42 ist. Sobald das j größer als 21 wird, werden Notizen ausgegeben:
</p>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="k">CREATE</span><span class="w"> </span><span class="k">OR</span><span class="w"> </span><span class="k">REPLACE</span><span class="w"> </span><span class="k">FUNCTION</span><span class="w"> </span><span class="n">foo</span><span class="p">(</span><span class="nb">int</span><span class="p">)</span><span class="w"> </span><span class="k">RETURNS</span><span class="w"> </span><span class="nb">integer</span><span class="w"> </span><span class="k">AS</span>
<span class="s">$</span><span class="dl">BODY</span><span class="s">$</span>
<span class="w"> </span><span class="k">DECLARE</span>
<span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="nb">INTEGER</span><span class="o">:=</span><span class="nv">$1</span><span class="p">;</span>
<span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="nb">INTEGER</span><span class="o">:=</span><span class="mf">0</span><span class="p">;</span>
<span class="w"> </span><span class="k">BEGIN</span>
<span class="w"> </span><span class="nl"><<ablock>></span><span class="w"> </span><span class="c1">-- Eine Schleife wird mit ablock benannt.</span>
<span class="w"> </span><span class="k">LOOP</span>
<span class="w"> </span><span class="n">j</span><span class="o">:=</span><span class="n">j</span><span class="o">+</span><span class="mf">7</span><span class="p">;</span>
<span class="w"> </span><span class="k">EXIT</span><span class="w"> </span><span class="n">ablock</span><span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="n">j</span><span class="o">>=</span><span class="n">i</span><span class="p">;</span><span class="w"> </span><span class="c1">-- Die Schleife endet wenn j>=i wird</span>
<span class="w"> </span><span class="k">CONTINUE</span><span class="w"> </span><span class="n">ablock</span><span class="w"> </span><span class="k">WHEN</span><span class="w"> </span><span class="n">j</span><span class="o"><</span><span class="p">(</span><span class="n">i</span><span class="o">/</span><span class="mf">2</span><span class="p">)</span><span class="w"> </span><span class="p">;</span><span class="w"> </span><span class="c1">-- falls j größer dem halben i ist, wird der folgende Block durchlaufen:</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">' %'</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="p">;</span>
<span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">LOOP</span><span class="w"> </span><span class="n">ablock</span><span class="p">;</span>
<span class="w"> </span><span class="k">RETURN</span><span class="w"> </span><span class="n">j</span><span class="p">;</span>
<span class="w"> </span><span class="k">END</span><span class="p">;</span>
<span class="s">$</span><span class="dl">BODY</span><span class="s">$</span><span class="w"> </span><span class="k">LANGUAGE</span><span class="w"> </span><span class="n">plpgsql</span><span class="p">;</span>
<span class="k">Select</span><span class="w"> </span><span class="n">foo</span><span class="p">(</span><span class="mf">42</span><span class="p">);</span>
</pre></div>
<div class="mw-highlight mw-highlight-lang-text mw-content-ltr" dir="ltr"><pre><span></span>Ausgabe mit pgAdmin:
HINWEIS: 21
HINWEIS: 28
HINWEIS: 35
Total query runtime: 27 ms.
1 row retrieved.
</pre></div>
<div class="mw-heading mw-heading4"><h4 id="WHILE_LOOP_Schleife">WHILE LOOP Schleife</h4></div>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="n">WHILE</span><span class="w"> </span><span class="n">boolean_expression</span><span class="w"> </span><span class="n">LOOP</span>
<span class="w"> </span><span class="n">statements</span><span class="p">;</span>
<span class="k">END</span><span class="w"> </span><span class="n">LOOP</span>
</pre></div>
<p>Die einfache <code>WHILE LOOP</code> Schleife wird nur durchlaufen wenn die Eingangsbedingung erfüllt ist, und endet sobald die Bedingung nicht mehr zutrifft. Auch diese Variante kann benannt werden.
</p>
<div class="mw-heading mw-heading4"><h4 id="FOR_Schleifen">FOR Schleifen</h4></div>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="k">FOR</span><span class="w"> </span><span class="n">varname</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="k">expression</span><span class="w"> </span><span class="mf">..</span><span class="w"> </span><span class="k">expression</span><span class="w"> </span><span class="n">LOOP</span><span class="w"> </span><span class="c1">-- FOR i IN REVERSE 10..2 BY 2 LOOP</span>
<span class="w"> </span><span class="n">statements</span><span class="p">;</span>
<span class="k">END</span><span class="w"> </span><span class="n">LOOP</span><span class="p">;</span>
</pre></div>
<p>Die <code>FOR</code>-Schleife zählt eine Indexvariable vom Type <code>INTEGER</code> die auch automatisch erstellt wird von einem festgelegten Startwert bis zu einem festgelegten Endwert. Start- und Zielwert sind durch zwei Punkte getrennt. Gibt man das Schlüsselwort REVERSE nach dem IN an, so wird vom größeren zum kleineren Wert heruntergezählt. Die Schrittweite ist aber in jedem Falle positiv anzugeben, auch beim Rückwärtszählen.
</p><p>Die <code>FOR</code>-Schleife kann auch zum Durchlaufen einer Abfrage verwendet werden:
</p>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="k">FOR</span><span class="w"> </span><span class="n">wertliste</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="n">query</span><span class="w"> </span><span class="n">LOOP</span>
<span class="w"> </span><span class="n">statements</span><span class="p">;</span>
<span class="k">END</span><span class="w"> </span><span class="n">LOOP</span>
</pre></div>
<p>Die “wertliste” ist dabei eine Variable die die Felder der Abfrage “query” übernimmt. Die Variable wertliste übernimmt beim Durchlaufen der Abfrage jede Zeile der Abfrage einmal. Mit dieser Zeile wird dann der Schleifenkörper durchlaufen.
</p><p>Verwendet man statt einer erst “vor Ort” bei der FOR-Schleife definierten Abfrage (bzw. einem SQL-String via EXECUTE) einen expliziten Cursor, so wird in ausreichend neuen PostgreSQL-Versionen (9.x) die Schleifenvariable “wertliste” (analog zum Schleifenindex einer numerischen FOR-Schleife) implizit deklariert.
</p>
<div class="mw-highlight mw-highlight-lang-postgresql mw-content-ltr" dir="ltr"><pre><span></span><span class="k">CREATE</span><span class="w"> </span><span class="k">FUNCTION</span><span class="w"> </span><span class="n">foo</span><span class="p">()</span><span class="w"> </span><span class="k">RETURNS</span><span class="w"> </span><span class="nb">void</span><span class="w"> </span><span class="k">AS</span>
<span class="s">$</span><span class="dl">body</span><span class="s">$</span>
<span class="w"> </span><span class="k">DECLARE</span>
<span class="w"> </span><span class="n">meinaktuellerview</span><span class="w"> </span><span class="nb">RECORD</span><span class="p">;</span><span class="w"> </span><span class="c1">-- die Variable meinaktuellerview wird als Type RECORD festgelegt.</span>
<span class="w"> </span><span class="k">BEGIN</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'Refreshing materialized views...'</span><span class="p">;</span>
<span class="w"> </span><span class="k">FOR</span><span class="w"> </span><span class="n">meinaktuellerview</span><span class="w"> </span><span class="k">IN</span><span class="w"> </span><span class="k">SELECT</span><span class="w"> </span><span class="n">viewname</span><span class="p">,</span><span class="w"> </span><span class="n">viewsql</span><span class="w"> </span><span class="k">FROM</span><span class="w"> </span><span class="n">fooviews</span><span class="w"> </span><span class="k">ORDER</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">foo</span><span class="mf">.</span><span class="n">fooid</span><span class="w"> </span><span class="k">LOOP</span>
<span class="w"> </span><span class="c1">-- jetzt beinhaltet "meinaktuellerview" einen Datensatz aus der Tabelle fooviews</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'Ersetzen des materialisierten views %s ...'</span><span class="p">,</span><span class="w"> </span><span class="n">quote_ident</span><span class="p">(</span><span class="n">meinaktuellerview</span><span class="mf">.</span><span class="n">viewname</span><span class="p">);</span>
<span class="w"> </span><span class="k">EXECUTE</span><span class="w"> </span><span class="s1">'TRUNCATE TABLE '</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">quote_ident</span><span class="p">(</span><span class="n">meinaktuellerview</span><span class="mf">.</span><span class="n">viewname</span><span class="p">);</span><span class="w"> </span><span class="c1">-- Inhalt aus einer Tabelle löschen</span>
<span class="w"> </span><span class="k">EXECUTE</span><span class="w"> </span><span class="s1">'INSERT INTO '</span>
<span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">quote_ident</span><span class="p">(</span><span class="n">meinaktuellerview</span><span class="mf">.</span><span class="n">viewname</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="s1">' '</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">meinaktuellerview</span><span class="mf">.</span><span class="n">viewsql</span><span class="p">;</span>
<span class="w"> </span><span class="c1">-- eine in der Tabelle gespeicherte Abfrage wird an eine Tabelle angefügt.</span>
<span class="w"> </span><span class="k">END</span><span class="w"> </span><span class="k">LOOP</span><span class="p">;</span>
<span class="w"> </span><span class="k">RAISE</span><span class="w"> </span><span class="k">NOTICE</span><span class="w"> </span><span class="s1">'Erledigt: materialisierte Views sind aktuell.'</span><span class="p">;</span>
<span class="w"> </span><span class="k">END</span><span class="p">;</span>
<span class="s">$</span><span class="dl">body</span><span class="s">$</span><span class="w"> </span><span class="k">LANGUAGE</span><span class="w"> </span><span class="n">plpgsql</span><span class="p">;</span>
</pre></div>
<div class="mw-heading mw-heading2"><h2 id="Weblinks">Weblinks</h2></div>
<ul><li><a rel="nofollow" class="external text" href="https://www.postgresql.org/docs/current/plpgsql.html">PostgreSQL PL/pgSQL Documentation</a> (englisch, aktuelle PostgreSQL Version)</li>
<li>Einführung in <a rel="nofollow" class="external text" href="https://www.postgresqltutorial.com/introduction-to-postgresql-stored-procedures/">PL/pgSQL</a> (englisch)</li></ul>
<div class="mw-heading mw-heading2"><h2 id="Einzelnachweise">Einzelnachweise</h2></div>
<ol class="references">
<li id="cite_note-1"><span class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span class="reference-text"><a rel="nofollow" class="external text" href="https://www.postgresql.org/about/licence/"><i>PostgreSQL: License</i></a> – Seite bei <i>PostgreSQL.org</i>; Stand: 17. September 2011 (englisch).</span>
</li>
<li id="cite_note-2"><span class="mw-cite-backlink"><a href="#cite_ref-2">↑</a></span> <span class="reference-text"><span class="cite"><a rel="nofollow" class="external text" href="https://www.postgresql.org/docs/current/plpgsql-structure.html"><i>PostgreSQL 9.1.0 Documentation, PL/pgSQL - SQL Procedural Language, Structure of PL/pgSQL.</i></a> PostgreSQL.org, 12. September 2011,<span class="Abrufdatum"> abgerufen am 17. September 2011</span> (englisch).</span><span style="display: none;" class="Z3988" title="ctx_ver=Z39.88-2004&rft_val_fmt=info%3Aofi%2Ffmt%3Akev%3Amtx%3Adc&rfr_id=info%3Asid%2Fde.wikipedia.org%3APL%2FpgSQL&rft.title=PostgreSQL+9.1.0+Documentation%2C+PL%2FpgSQL+-+SQL++Procedural+Language%2C+Structure+of+PL%2FpgSQL&rft.description=PostgreSQL+9.1.0+Documentation%2C+PL%2FpgSQL+-+SQL++Procedural+Language%2C+Structure+of+PL%2FpgSQL&rft.identifier=https%3A%2F%2Fwww.postgresql.org%2Fdocs%2Fcurrent%2Fplpgsql-structure.html&rft.publisher=PostgreSQL.org&rft.date=2011-09-12&rft.language=en"> </span></span>
</li>
</ol></div><!--htdig_noindex--><div><div class="zim-footer">
Dieser Artikel wurde von <a class="external text" title="Zuletzt bearbeitet am 2024-03-16" href="https://de.wikipedia.org/wiki/?title=PL%2FpgSQL&oldid=243155807">Wikipedia</a> herausgegeben. Der Text ist unter <a class="external text" href="https://creativecommons.org/licenses/by-sa/4.0/deed.de">Creative Commons Attribution-Share Alike 4.0</a> verfügbar, sofern nicht anders angegeben. Für die Mediendateien können zusätzliche Bedingungen gelten.
</div>
</div><!--/htdig_noindex--></div>
</div>
</main>
</div>
</div>
</div>
<script src="../_webp_/webpHandler.js"></script>
</body></html>